package com.logica.mdm.webservices.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.cxf.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.logica.mdm.webservices.dao.CrmContactDao;
import com.logica.mdm.webservices.dataobject.crm.contact.AddressData;
import com.logica.mdm.webservices.dataobject.crm.contact.ContactData;
import com.logica.mdm.webservices.dataobject.mdm.CLuAddressTypeConstants;
import com.logica.mdm.webservices.dataobject.mdm.CleansePutTypedResponse;
import com.logica.mdm.webservices.messages.CleansePutCrmContactCompositeRequest;
import com.logica.mdm.webservices.utils.SiperianRequestUtils;
import com.siperian.sif.client.SiperianClient;
import com.siperian.sif.message.SiperianRequest;
import com.siperian.sif.message.mrm.CleansePutResponse;
import com.siperian.sif.message.nexity.mappings.CleansePutCrmAddressRelRequest;

/**
 * CrmContactDao implementation backed by Informatica MDM Hub SiperianClient.
 * Note that due to SiperianClient not being thread-safe, this class is not thread-safe either.
 * @author Fabien Crespel <fabien.crespel@logica.com>
 */
public class SiperianClientCrmContactDao implements CrmContactDao {

	private static final Logger logger = LoggerFactory.getLogger(SiperianClientCrmContactDao.class);
	
	protected SiperianClient siperianClient;
	
	/**
	 * Constructor taking an existing SiperianClient instance.
	 * @param siperianClient
	 */
	public SiperianClientCrmContactDao(SiperianClient siperianClient) {
		this.siperianClient = siperianClient;
	}
	
	@Override
	public List<CleansePutTypedResponse> cleansePutCrmContact(CleansePutCrmContactCompositeRequest crmContactCompositeRequest) throws Exception {
		ContactData contact = crmContactCompositeRequest.getContact();
		
		// Init the requests/responses lists
		List<SiperianRequest> requests = new ArrayList<SiperianRequest>();
		List<CleansePutTypedResponse> responses = new ArrayList<CleansePutTypedResponse>();

		// Party
		requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmContact", crmContactCompositeRequest, contact));
		
		// Electronic Address
		if (!StringUtils.isEmpty(contact.getContactEmail()))
			requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmUrl", crmContactCompositeRequest, contact));
		
		// Phone
		if (!StringUtils.isEmpty(contact.getWorkPhone()))
			requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmPhoneBur", crmContactCompositeRequest, contact));
		if (!StringUtils.isEmpty(contact.getHomePhone()))
			requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmPhoneDom", crmContactCompositeRequest, contact));
		if (!StringUtils.isEmpty(contact.getWorkFax()))
			requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmPhoneFax", crmContactCompositeRequest, contact));
		if (!StringUtils.isEmpty(contact.getCellularPhone()))
			requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmPhoneMob", crmContactCompositeRequest, contact));
		
		// Person Details
		requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmPersonDetails", crmContactCompositeRequest, contact));
		
		// Address
		if (contact.getListOfAddress() != null) {
			for (AddressData address : contact.getListOfAddress().getAddress()) {
				// CleansePutCrmAddress
				requests.add(SiperianRequestUtils.buildCleansePutRequest("CrmAddress", crmContactCompositeRequest, address));
				
				// CleansePutCrmAddressRel
				CleansePutCrmAddressRelRequest request = (CleansePutCrmAddressRelRequest) SiperianRequestUtils.buildCleansePutRequest("CrmAddressRel", crmContactCompositeRequest, contact);
				request.getCrmAddressRelInput().setPartyId(contact.getId());
				request.getCrmAddressRelInput().setAddressId(address.getId());
				if (address.getId().equals(contact.getAlternateAddressId())) {
					// Primary
					request.getCrmAddressRelInput().setAddressType(CLuAddressTypeConstants.TYPE_PERSO_PRINCIPALE);
				} else {
					// Secondary
					request.getCrmAddressRelInput().setAddressType(CLuAddressTypeConstants.TYPE_PERSO_SECONDAIRE);
				}
				requests.add(request);
			}
		}
		
		// Perform the requests
		logger.info("START processing of " + requests.size() + " requests...");
		for (SiperianRequest request : requests) {
			logger.info("Processing '" + request.getClass().getSimpleName() + "'...");
			CleansePutResponse response = (CleansePutResponse) siperianClient.process(request);
			responses.add(new CleansePutTypedResponse(response));
		}
		logger.info("END processing of " + requests.size() + " requests.");
		
		return responses;
	}

}
